package com.thinkgsp.sys.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.dao.SaltSource;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.thinkgsp.jxc.model.Dept;
import com.thinkgsp.sys.model.SysUser;
import com.thinkgsp.sys.model.SysUserDept;
import com.thinkgsp.sys.model.SysUserInvAdd;
import com.thinkgsp.sys.model.SysUserRole;
import com.thinkgsp.sys.persistence.SysUserMapper;
import com.thinkgsp.sys.service.SysUserService;
import com.thinkgsp.sys.service.UserExistsException;

@Service("userService")
public class SysUserServiceImpl extends BaseServiceImpl implements SysUserService {

	
	@Autowired
	private PasswordEncoder passwordEncoder;
	
	@Autowired(required=false)
	private SaltSource saltSource;
	
	@Autowired
	private SysUserMapper userMapper;
	
	public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
		this.passwordEncoder = passwordEncoder;
	}
	
	public void setSysUserMapper(SysUserMapper userMapper) {
		this.userMapper = userMapper;
	}
	
	public SysUser getUser(Integer userId) {
		SysUser user = userMapper.getUser(userId);
		for(Dept dept : user.getDepts()) {
			if(dept.isDefaultDept()) {
				user.setLogonDept(dept);
				break;
			}
		}
		return user;
	}

	public SysUser getUserByUsername(String username) {
		SysUser user = userMapper.loadUserByUsername(username);
		for(Dept dept : user.getDepts()) {
			if(dept.isDefaultDept()) {
				user.setLogonDept(dept);
				log.debug("user:" + user.getUsername() + " logon dept:" + dept.getDeptName());
				break;
			}
		}
		if(user.getLogonDept() == null) {
			log.debug("user:'" + user.getUsername() + "' not default dept for logon.");
		}
		return user;
	}

	public List<SysUser> getUsers() {
		return userMapper.getUsers();
	}

	public SysUser saveUser(SysUser user) throws UserExistsException {
		boolean passwordChanged = false;
		String curPwd = userMapper.getUserPassword(user.getUserId());
		if(curPwd != null && curPwd.equals(user.getPassword())) {
			passwordChanged = false;
		} else {
			passwordChanged = true;
		}
		if(passwordChanged) {
			if(passwordEncoder != null) {
				if(saltSource == null) {
					user.setPassword(passwordEncoder.encodePassword(user.getPassword(), null));
					log.warn("SaltSource not set, encrypting password w/o salt");
				} else {
					user.setPassword(passwordEncoder.encodePassword(user.getPassword(), 
							saltSource.getSalt(user)));
				}			
			} else {
				log.warn("PasswordEncoder not set, skipping password encryption...");
			}
		}
		
		try {
			if(user.getUserId() == null || user.getUserId() == 0) {
				userMapper.insertUser(user);
			} else {
				userMapper.updateUser(user);
				//userMapper.deleteUserRole(user.getUserId());
				//userMapper.deleteUserInvAddByUserId(user.getUserId());
			}
//			for(SysRole role : user.getRoles()) {
//				SysUserRole ur = new SysUserRole();
//				ur.setUserId(user.getUserId());
//				ur.setRoleId(role.getRoleId());
//				userMapper.insertUserRole(ur);
//			}
//			for(InventoryAdd ia : user.getInvadds()) {
//				SysUserInvAdd ui = new SysUserInvAdd();
//				ui.setUserId(user.getUserId());
//				ui.setInvaddId(ia.getId());
//				ui.setDefaultInvAdd(ia.isDefaultInvAdd());
//				userMapper.insertUserInvAdd(ui);
//			}
		} catch(Exception e) {
			log.warn(e.getMessage());
			throw new UserExistsException("User '" + user.getUsername() + "' already exists!");
		}
		return user;
	}

	public void removeUser(Integer userId) {
		log.debug("removing user:" + userId);
		userMapper.deleteUserRole(userId);
		userMapper.deleteUser(userId);
	}

	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException {
		//return userMapper.loadUserByUsername(username);
		SysUser user = userMapper.loadUserByUsername(username);
		if(user==null)
			throw new UsernameNotFoundException("用户不存在");
		for(Dept dept : user.getDepts()) {
			if(dept.isDefaultDept()) {
				user.setLogonDept(dept);
				log.debug("user:" + user.getUsername() + " logon dept:" + dept.getDeptName());
				break;
			}
		}
		if(user.getLogonDept() == null) {
			log.debug("user:'" + user.getUsername() + "' not default dept for logon.");
		}
		return user;
	}

	public void addRole(Integer userId, Integer roleId) {
		SysUserRole ur = new SysUserRole();
		ur.setUserId(userId);
		ur.setRoleId(roleId);
		userMapper.insertUserRole(ur);
	}

	public void deleteRole(Integer userId, Integer roleId) {
		userMapper.deleteUserRoleSingle(userId, roleId);
	}

	public void addUserInvAdd(Integer userId, Integer invAddId) {
		SysUserInvAdd ui = new SysUserInvAdd();
		ui.setUserId(userId);
		ui.setInvaddId(invAddId);
		ui.setDefaultInvAdd(false);
		userMapper.insertUserInvAdd(ui);
	}

	public void delelteUserInvAdd(Integer userId, Integer invAddId) {
		userMapper.deleteUserInvAddSingle(userId, invAddId);
	}

	public void setDefaultInvAdd(Integer userId, Integer invAddId) {
		userMapper.clearDefaultInvAdd(userId);
		userMapper.setDefaultInvAdd(userId, invAddId);
	}

	public void addUserDept(Integer userId, Integer deptId) {
		SysUserDept ud = new SysUserDept();
		ud.setUserId(userId);
		ud.setDeptId(deptId);
		ud.setDefaultDept(false);
		userMapper.insertUserDept(ud);
		
	}

	public void deleteUserDept(Integer userId, Integer deptId) {
		userMapper.deleteUserDeptSingle(userId, deptId);
		
	}

	public void setDefaultDept(Integer userId, Integer deptId) {
		userMapper.clearDefaultDept(userId);
		userMapper.setDefaultDept(userId, deptId);
	}

}
